//***************************************************************************//
//* 版权所有  www.sh-easy.cc
//*
//* 内容摘要：环形队列，由外层负责锁保护
//*	
//* 当前版本：V1.0		
//* 作    者：zhfayuan
//* 完成日期：2015-12-26
//**************************************************************************//
#ifndef _SD_RING_BUFF_H_
#define _SD_RING_BUFF_H_

#include <string.h>
template<typename T,int S>
class CSDRingBuff
{

private:
	T	data[S];
	int	ini;
	int	end;
	int	len;
public:

	CSDRingBuff()
	{
		ini=0;
		end=0;
		len=0;
	}
	
	int push(const T *in,int l)
	{
		if (size()<len+l)
			return 0;
	
		int free = size()-end;
	
		if (free>=l)
		{
			memcpy(data+end,in,l*sizeof(T));
	
			end+=l;

			if (end==size())
				end=0;
		} 
		else 
		{
			memcpy(data+end,in,free*sizeof(T));
			memcpy(data,in+free,(l-free)*sizeof(T));
	
			end=l-free;
		}
	
		len+=l;
	
		return l;
	}

	T pop()
	{
		T out;
		pop(&out,1,true);
		return out;
	}

	T peek()
	{
		T out;
		pop(&out,1,false);
		return out;
	}

	int pop(T *out,int l)
	{
		return pop(out,l,true);
	}

	int peek(T *out,int l)
	{
		return pop(out,l,false);
	}
	
	int pop(T *out,int l,bool remove)
	{
		if (len<l)
			return 0;
	
		unsigned int total = size()-ini;
	
		if (total>=l)
		{
			memcpy(out,data+ini,l*sizeof(T));
	
			if (remove)
				ini+=l;

			if (ini==size())
				ini=0;
		} 
		else 
		{
			memcpy(out,data+ini,total*sizeof(T));
			memcpy(out+total,data,(l-total)*sizeof(T));
	
			if (remove)
				ini=l-total;
		}
	
		if (remove)
			len-=l;
	
		return l;
	}

	int remove(int l)
	{
		if (len<l)
			return 0;
	
		int total = size()-ini;
	
		if (total>=l)
		{
			ini+=l;
		} 
		else 
		{
			ini=l-total;
		}
	
		len-=l;
	
		return l;
	}
	int size()
	{
		return S;
	}
	int length()
	{
		return len;
	}

	void clear()
	{
		ini = end;
		len = 0;
	}
	
};

#endif
